#ifndef COMMAND_LOGIN_COMMAND_H_
#define COMMAND_LOGIN_COMMAND_H_

#include "command.h"

#ifdef _WIN32
#pragma warning( push )
#pragma warning( disable : 4200 )
#endif

#pragma pack(1)
namespace Cmd
{
        enum //CMD_LOGIN
        {
                SCMD_LOGIN_NULL	                        = 0x0000,
                SCMD_LOGIN_REQ_GATEWAY                  = 0x0001,	//client->loginserver:登录验证，请求网关地址
                SCMD_LOGIN_RES_GATEWAY                  = 0x0002,	//loginserver->client:登录验证返回,携带分配的GatewayServer地址
                SCMD_LOGIN_GATEWAY                      = 0x0003,	//client->gatewayserv:请求登录GatewayServer
                SCMD_LOGIN_GATEWAY_RESPONSE             = 0x0004,       //gatewayserv->client:登录GatewayServer返回
                SCMD_LOGIN_BASE_INFO_RESPONSE           = 0x0005,       //gatewaysv->client:登陆后返回用户基本信息
                SCMD_LOGIN_LOGOUT                       = 0x0006,	//client->gateawyserv:用户请求下线
                SCMD_LOGIN_SYNC_TIME                    = 0x0007,	//gatewayserv->client:同步client的时间与服务器时间一致
                SCMD_LOGIN_NOTIFY_LOGOUT                = 0x0008,       //gateway->client:通知用户下线
                SCMD_LOGIN_CHECK_VERSION                = 0x0009,       //client->server:client定时请求检测版本
                SCMD_LOGIN_CHECK_VERSION_RES            = 0x000A,       //server->client:server返回版本状态
                SCMD_LOGIN_NOTIFY_LOGOUT_WITH_REASON    = 0x000B,       //gateway->client:通知用户下线
                SCMD_APP_LOGIN_GATEWAY                  = 0x000C,	//app->gatewayserv: APP请求登录GatewayServer
                SCMD_APP_LOGIN_GW                       = 0x000D,       //app->gatewayserv: APP请求登录GatewayServer
                SCMD_DEVICE_INFO                        = 0x000E,       //app->gatewayserv: APP, client发送客户端信息.
                SCMD_LOGIN_GATEWAY_UNIFIED              = 0x000F,       // 统一的用户登录接口
                SCMD_LOGIN_GATEWAY_UNREGISTERED_REQ     = 0x0010,       // 未注册用户请求登录
                SCMD_LOGIN_GATEWAY_UNREGISTERED_RES     = 0x0011,       // 返回未登录用户登录结果
                SCMD_LOGIN_CHK_BEST_AP                  = 0x0012,       // c->s: 检测最优接入点. 用于决定客户端是否群ping
                SCMD_LOGIN_CHK_BEST_AP_RES              = 0x0013,       // s->c: 检测最有接入点返回
                SCMD_LOGIN_ECHO_PING                    = 0x0014,       // c<->s:ping指令
        };

        struct stLoginReqGateway :
                t_NullCmd
        {
                stLoginReqGateway() :
                        t_NullCmd(CMD_LOGIN, SCMD_LOGIN_REQ_GATEWAY)
                {
                        bzero(account_, sizeof(account_));
                        bzero(passwd_,  sizeof(passwd_));
                        version_id_ = 0;
                        version_type_ = 0;
                }
                BYTE account_[MAX_ACCOUNT_SIZE+1];      //用户帐号
                BYTE passwd_[MAX_PASSWORD_SIZE+1];      //passwd m5
                DWORD version_id_;                      //客户端使用版本号
                BYTE  version_type_;                    //eClientVersionType
                char reserved_[7];                      //备用字段
        };
        struct stLoginResGateway :
                t_NullCmd
        {
                stLoginResGateway() :
                        t_NullCmd(CMD_LOGIN, SCMD_LOGIN_RES_GATEWAY)
                {
                        user_id_ = 0;
                        bzero(gateway_ip_, sizeof(gateway_ip_));
                        gateway_port_ = 0;
                        token_ = 0;
                        latest_version_ = 0;
                        reserved2_ = 0;
                        ret_code_ = eLoginRetCode_Fail;
                        bzero(token32_, sizeof(token32_));
                        extra_len = 0;
                }
                uint32_t get_size()
                {
                        return sizeof(*this)+extra_len*sizeof(extra[0]);
                }
                DWORD user_id_; 
                char gateway_ip_[MAX_IP_LENGTH+1];      //分配到的网关的ip
                WORD gateway_port_;                     //分配到的网关的port
                DWORD token_;                           // LoginServer生成token
                DWORD latest_version_;                  // 客户端最新版本
                DWORD reserved2_;	                // 备用字段2
                WORD ret_code_;		                // eLoginRetCode
                char token32_[MAX_TOKEN32_SIZE+1];      // 平台生成公共token
                uint16_t extra_len;
                char extra[0];                          // json格式
                // {
                //      "redirect":1,                   //是否重定向. 0-no 1-yes
                //      "newidc":123,                   //重定向的idc的id
                //      "newip":"127.0.0.1",            //重定向的idc的一个ip
                //      "newport":1234                  //重定向的idc的一个port
                // }
        };
        struct stLoginGateway :
                t_NullCmd
        {
                stLoginGateway() :
                        t_NullCmd(CMD_LOGIN, SCMD_LOGIN_GATEWAY)
                {
                        user_id_ = 0;
                        version_ = 0;
                        mac_ = 0;
                        token_ = 0;
                        reserved1_ = 0;
                        reserved2_ = 0;
                }
                DWORD user_id_;                         //用户id
                DWORD version_;                         //版本号
                QWORD mac_;                             //mac地址
                DWORD token_;                           //登录token
                DWORD reserved1_;                       //备用字段
                DWORD reserved2_;                       //备用字段
        };
        struct stLoginGatewayResponse :
                t_NullCmd
        {
                stLoginGatewayResponse() :
                        t_NullCmd(CMD_LOGIN, SCMD_LOGIN_GATEWAY_RESPONSE)
                {
                        ret_code_ = eLoginRetCode_Fail;
                }
                WORD ret_code_;				//eLoginRetCode
        };
        enum eGender
        {
                eGender_male = 0x00,			//男性
                eGender_female,				//女性
                eGender_androgynous,			//双性
        };
        struct stLoginBaseInfoResponse :
                t_NullCmd
        {
                stLoginBaseInfoResponse():
                        t_NullCmd(CMD_LOGIN, SCMD_LOGIN_BASE_INFO_RESPONSE)
                {
                        user_id_ = 0;
                        gender_ = eGender_male;
                        online_status_ = USER_STATE_ONLINE;
                        bzero(account_, sizeof(account_));
                        bzero(nickname_, sizeof(nickname_));
                        bzero(mood_, sizeof(mood_));
                        bzero(avatar_, sizeof(avatar_));
                }
                DWORD user_id_;				//用户ID
                BYTE gender_;				//性别 eGender
                BYTE online_status_;			//在线状态 eIMOnlineStatus
                BYTE account_[MAX_ACCOUNT_SIZE+1];      //帐号
                BYTE nickname_[MAX_NAME_SIZE+1];	//昵称
                BYTE mood_[MAX_MOOD_SIZE+1];		//心情
                BYTE avatar_[MAX_AVATAR_SIZE+1];	//头像文件名
        };
        struct stLoginLogout:
                t_NullCmd
        {
                stLoginLogout():
                        t_NullCmd(CMD_LOGIN, SCMD_LOGIN_LOGOUT)
                {
                }
        };
        struct stLoginSyncTime :
                t_NullCmd
        {
                stLoginSyncTime():
                        t_NullCmd(CMD_LOGIN, SCMD_LOGIN_SYNC_TIME)
                {
                        time_ = 0;
                }
                DWORD time_;				//服务器时间
        };
        struct stLoginNotifyLogout:
                t_NullCmd
        {
                stLoginNotifyLogout():
                        t_NullCmd(CMD_LOGIN, SCMD_LOGIN_NOTIFY_LOGOUT)
                {
                        reason_ = eLogoutReason_null;
                }
                BYTE reason_;                                   //eLogoutReason
        };
        struct stLoginCheckVersion:
                t_NullCmd
        {
                stLoginCheckVersion():
                        t_NullCmd(CMD_LOGIN, SCMD_LOGIN_CHECK_VERSION)
                {
                        version_type_ = eClientVersionType_outer;
                        version_id_   = 0;
                }
                BYTE  version_type_;                            // 版本类型：eClientVersionType
                DWORD version_id_;                              // 版本号
        };
        struct stLoginCheckVersionRes:
                t_NullCmd
        {
                stLoginCheckVersionRes():
                        t_NullCmd(CMD_LOGIN, SCMD_LOGIN_CHECK_VERSION_RES)
                {
                        latest_version_ = 0;
                        force_update_  = 0;
                }
                DWORD latest_version_;                          //当前最新的版本
                BYTE force_update_;                             //是不死需要强制升级:0-no, 1-yes
        };
        struct stLoginNotifyLogoutWithReason:
                t_NullCmd
        {
                stLoginNotifyLogoutWithReason():
                        t_NullCmd(CMD_LOGIN, SCMD_LOGIN_NOTIFY_LOGOUT_WITH_REASON)
                {
                        minutes_ = 0;
                        bzero(reason_, sizeof(reason_));
                }
                WORD minutes_;                                  //不能登录的时长
                char reason_[256];                              //下线原因
        };
        struct stAppLoginGateway :
                t_NullCmd
        {
                stAppLoginGateway() :
                        t_NullCmd(CMD_LOGIN, SCMD_APP_LOGIN_GATEWAY)
                {
                        user_id_ = 0;
                        version_ = 0;
                        token_ = 0;
                        bzero(brand_, sizeof(brand_));
                        bzero(sdk_version_, sizeof(sdk_version_));
                        bzero(mac_, sizeof(mac_));
                        bzero(cellphone_num_, sizeof(cellphone_num_));
                        bzero(device_id_, sizeof(device_id_));
                        reserved1_ = 0;
                        reserved2_ = 0;
                }
                DWORD user_id_;                                 //用户ID
                DWORD version_;                                 //版本号
                DWORD token_;                                   //登录token

                char brand_[MAX_APP_BRAND_SIZE+1];              //品牌
                char sdk_version_[MAX_APP_SDK_VERSION_SIZE+1];  //sdk版本
                char mac_[MAX_MAC_ADDR_SIZE+1];                 //mac地址
                char cellphone_num_[MAX_CELLPHONE_NUM_SIZE+1];  //电话号码
                char device_id_[MAX_APP_DEVICE_ID_SIZE+1];      //设备id

                DWORD reserved1_;                               //备用字段1
                DWORD reserved2_;                               //备用字段2
        };
        struct stAppLoginGW:
                t_NullCmd
        {
                stAppLoginGW():
                        t_NullCmd(CMD_LOGIN, SCMD_APP_LOGIN_GW)
                {
                        user_id_ = 0;
                        version_ = 0;
                        token_ = 0;
                        size_ = 0;
                }
                DWORD getSize()
                {
                        return sizeof(*this)+size_*sizeof(extra_info_[0]);
                }
                DWORD user_id_;
                DWORD version_;
                DWORD token_;
                WORD size_;
                char extra_info_[0]; // json格式
        };

        struct stDeviceInfo:
            t_NullCmd
        {
            stDeviceInfo() :
                t_NullCmd(CMD_LOGIN, SCMD_DEVICE_INFO)
            {
                user_id_ = 0;
                dev_type_ = 0;
                os_type_ = 0;
                bzero(dev_id_, sizeof(dev_id_));
            }
            
            DWORD user_id_;
            DWORD dev_type_;
            DWORD os_type_;
            char dev_id_[DEVICE_ID_LENGTH];
        };

        struct stLoginGatewayUnified :
                t_NullCmd
        {
                stLoginGatewayUnified() :
                        t_NullCmd(CMD_LOGIN, SCMD_LOGIN_GATEWAY_UNIFIED)
                {
                        user_id_ = 0;
                        version_ = 0;
                        token_ = 0;
                        login_flags_ = 0;
                        size_ = 0;
                }
                DWORD user_id_;      //用户ID
                DWORD version_;      //版本号
                DWORD token_;        //登录令牌
                DWORD login_flags_;  // 登录标志, 参考 eUserLoginType
                WORD size_;            // json字符串长度
                char extra_info_[0];   // json格式
                /* extera_info example:
                {"dvt":3,  // device type  ref: eTerminalType
                  "ost":4,  // os type ref: eOSType
                  "dvi":"abcdefg",  //device id
                  "mac":"abcdefg",  // mac
                  "bra":"ipad",  // brand 
                  "svn":"1.0",  // sdk version
                  "mob":"1234567890",  // phone number
                  "avn":"1.0"  // app version
                 }
                */
        };

        struct stLoginGatewayUnregisteredReq :
                t_NullCmd
        {
                stLoginGatewayUnregisteredReq() :
                        t_NullCmd(CMD_LOGIN, SCMD_LOGIN_GATEWAY_UNREGISTERED_REQ)
                {
                        user_id_ = 0;
                        version_id_ = 0;
                        version_type_ = 0;
                }

                uint32_t user_id_;
                uint32_t version_id_;                   // 客户端使用版本号
                uint8_t version_type_;                  // eClientVersionType
        };

        struct stLoginGatewayUnregisteredRes :
                t_NullCmd
        {
                stLoginGatewayUnregisteredRes() :
                        t_NullCmd(CMD_LOGIN, SCMD_LOGIN_GATEWAY_UNREGISTERED_RES)
                {
                        user_id_ = 0;
                        bzero(gateway_ip_, sizeof(gateway_ip_));
                        gateway_port_ = 0;
                        token_ = 0;
                        latest_version_ = 0;
                        ret_code_ = eLoginRetCode_Fail;
                }

                uint32_t user_id_; 
                char gateway_ip_[MAX_IP_LENGTH+1];      // 分配到的网关的ip
                uint16_t gateway_port_;                 // 分配到的网关的port
                uint32_t token_;                        // LoginServer生成token
                uint32_t latest_version_;               // 客户端最新版本
                uint8_t ret_code_;		        // eLoginRetCode
        };
        struct stLoginChkBestAP:
                t_NullCmd
        {
                stLoginChkBestAP():
                        t_NullCmd(CMD_LOGIN, SCMD_LOGIN_CHK_BEST_AP)
                {
                }
        };
        struct stLoginChkBestAPRes:
                t_NullCmd
        {
                stLoginChkBestAPRes():
                        t_NullCmd(CMD_LOGIN, SCMD_LOGIN_CHK_BEST_AP_RES)
                {
                        need_ping = 0;
                        len = 0;
                }
                uint32_t get_size()
                {
                        return sizeof(*this)+len*sizeof(extra[0]);
                }
                uint8_t  need_ping;     //0-no 1-yes
                uint16_t len;           //extra`s len
                char extra[0];          //json格式
                // {
                //      "bestip":"123.123.123.123",
                //      "port":1234,
                // }
        };
        struct stLoginEchoPing:
                t_NullCmd
        {
                stLoginEchoPing():
                        t_NullCmd(CMD_LOGIN, SCMD_LOGIN_ECHO_PING)
                {
                        seq = 0;
                        timestamp = 0;
                        idc = -1;
                }
                uint16_t seq;           //client fill
                uint64_t timestamp;     //client fill
                int16_t idc;            //idc id. server fill
        };
};//namespace Cmd
#pragma pack()

#ifdef _WIN32
#pragma warning( pop )
#endif

#endif //COMMAND_LOGIN_COMMAND_H_
